package com.lzjn.code.web.controller;

import com.lzjn.code.common.model.JsonModel;
import com.lzjn.code.common.util.ContextHolderUtil;
import com.lzjn.code.common.util.FieldUtil;
import com.lzjn.code.web.entity.DataSource;
import com.lzjn.code.web.entity.GenerateCodeConfig;
import com.lzjn.code.web.entity.TableConfig;
import com.lzjn.code.web.entity.TableFieldConfig;
import com.lzjn.code.web.service.DataSourceService;
import com.lzjn.code.web.service.TableConfigService;
import com.lzjn.code.web.util.CodeGenerateUtil;
import com.lzjn.code.web.util.FileUtil;
import com.lzjn.code.web.util.ReadTableUtil;
import com.lzjn.code.web.util.ZipUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

@Controller
@RequestMapping("/generator")
public class GeneratorController {

	private static Logger log = LoggerFactory.getLogger(GeneratorController.class);

	@Autowired
	private DataSourceService dataSourceService;
	@Autowired
	private TableConfigService tableConfigService;
	private static GenerateCodeConfig gcConfigCache;

	@PostMapping("/generateConfig")
	@ResponseBody
	public JsonModel generateConfig(TableConfig tableConfig){

		JsonModel json = new JsonModel();

		try {

			DataSource dataSource = dataSourceService.getById(tableConfig.getDataSourceId());

			if(tableConfig.getTableNames().size() > 0) {

				ReadTableUtil readTableUtil = new ReadTableUtil();

				for(String tableName : tableConfig.getTableNames()) {

					tableConfig.setTableName(tableName);
					String description = readTableUtil.readTableCommentByName(dataSource, tableName);
					tableConfig.setDescription(description);
					tableConfig.setEntityName(FieldUtil.formatFieldCapital(tableName));
					tableConfig.setIsCheckbox("N");
					tableConfig.setIsPage("Y");
					tableConfig.setIsTree("N");
					tableConfig.setSearchColumnNum(3);
					tableConfig.setFormColumnNum(2);

					List<TableFieldConfig> fields =  readTableUtil.readTableColumn(dataSource, tableName);
					tableConfig.setFieldConfigs(fields);

					json.setMessage(tableConfigService.add(tableConfig));
				}
			}
			else {

				tableConfig.setEntityName(FieldUtil.formatFieldCapital(tableConfig.getTableName()));
				tableConfig.setIsCheckbox("N");
				tableConfig.setIsPage("Y");
				tableConfig.setIsTree("N");

				List<TableFieldConfig> fields =  new ReadTableUtil().readTableColumn(dataSource, tableConfig.getTableName());
				tableConfig.setFieldConfigs(fields);

				json.setMessage(tableConfigService.add(tableConfig));
			}


		} catch (Exception e) {

			json.setSuccess(false);
			json.setMessage("表单配置生成失败");
			log.error(e.getMessage(), e);
		}

		return json;
	}

	@PostMapping("/generateCodeConfig")
	public String generateCodeConfig(String ids, HttpServletRequest request) {

		try {

			GenerateCodeConfig generateCodeConfig = new GenerateCodeConfig();
			generateCodeConfig.setTableConfigIds(ids);

			// 参数默认值
			generateCodeConfig.setCodeType("java");
			if (gcConfigCache != null) {
				generateCodeConfig.setModuleName(gcConfigCache.getModuleName());
				generateCodeConfig.setSourceBasePackage(gcConfigCache.getSourceBasePackage());
				generateCodeConfig.setSqlBasePackage(gcConfigCache.getSqlBasePackage());
				generateCodeConfig.setPageBasePackage(gcConfigCache.getPageBasePackage());
				generateCodeConfig.setPageModel(gcConfigCache.getPageModel());
				generateCodeConfig.setAuthor(gcConfigCache.getAuthor());
			} else {
				generateCodeConfig.setSourceBasePackage("com.test.demo");
				generateCodeConfig.setSqlBasePackage("sql");
				generateCodeConfig.setPageBasePackage("views");
				generateCodeConfig.setAuthor("King");
			}

			request.setAttribute("generateCodeConfig", generateCodeConfig);

			String folderPath = "generator/template";

			File folderFile = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX + folderPath);
			File[] folders = folderFile.listFiles();

			List<String> templateFolders = new ArrayList<String>();

			if(folders != null && folders.length > 0) {

				for(File folder : folders) {

					templateFolders.add(folder.getName());
				}
			}

			request.setAttribute("templateFolders", templateFolders);

		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}

		return "views/tableConfig/generateCodeConfig";
	}


	@PostMapping("/generateCode")
	@ResponseBody
	public JsonModel generateCode(GenerateCodeConfig generateCodeConfig) {

		JsonModel json = new JsonModel();

		try {

			gcConfigCache = generateCodeConfig;

			TableConfig tableConfig = tableConfigService.getById(generateCodeConfig.getTableConfigIds());
			generateCodeConfig.setTableConfig(tableConfig);

			String basePath = ContextHolderUtil.getRequest().getServletContext().getRealPath("/") + "export/";

			String fileName = FieldUtil.getInitialSmall(generateCodeConfig.getTableConfig().getEntityName())
					+ "_" + System.currentTimeMillis();

			generateCodeConfig.setTargetPath(basePath + fileName);

			// 生成代码
			CodeGenerateUtil generate = new CodeGenerateUtil(generateCodeConfig);
			generate.invoke();

			ZipUtil.createZip(generateCodeConfig.getTargetPath(), generateCodeConfig.getTargetPath() + ".zip");

			json.setData(fileName + ".zip");
			json.setMessage("代码生成成功");
		} catch (Exception e) {
			json.setSuccess(false);
			json.setMessage("代码生成失败");
			log.error(e.getMessage(), e);
		}

		return json;
	}

	@GetMapping("/downloadZip")
	public void downloadZip(String fileName, HttpServletResponse response){

		String basePath = ContextHolderUtil.getRequest().getServletContext().getRealPath("/") + "export/";

		String filePath = basePath + fileName;

		try {

			FileUtil.downloadFile(filePath, response);
		} catch (Exception e) {

			log.error(e.getMessage(), e);
		}
	}
}
